<?php

namespace App\Admin\Controllers;

use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Show;
use Encore\Admin\Layout\Content;
use Illuminate\Routing\Controller;
use App\Models\Set;
use Illuminate\Support\Facades\Redirect;

class SetController extends Controller
{
    protected $title;
    protected $module = [];
    protected $model = false;
    protected $desc = [];
    /**
     * {@inheritdoc}
     */
    protected function title()
    {
        return $this->title ?? 'Title';
    }
    /**
     * Set description for following 4 action pages.
     *
     * @var array
     */

    public function __construct()
    {
        $this->model = new Set();
    }
    /**
     * Index interface.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->desc['index'] ?? trans('admin.list'))
            ->body($this->grid());
    }

    /**
     * Show interface.
     *
     * @param mixed   $id
     * @param Content $content
     *
     * @return Content
     */
    public function show($set, Content $content)
    {
        $rs = $this->model->where('name', $set)->orWhere('id', $set)->firstOrFail();
        $id = $rs->id;
        return $content
            ->title($this->title())
            ->description($this->desc['show'] ?? trans('admin.show'))
            ->body($this->detail($id));
    }

    /**
     * Edit interface.
     *
     * @param mixed   $id
     * @param Content $content
     *
     * @return Content
     */
    public function edit($set, Content $content)
    {
        $rs = $this->model->where('name', $set)->orWhere('id', $set)->firstOrFail();
        $this->name = $rs->name;
        $id = $rs->id;
        return $content
            ->title($this->title())
            ->description($this->desc['edit'] ?? trans('admin.edit'))
            ->body($this->form()->edit($id));
    }

    /**
     * Create interface.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function create(Content $content)
    {
        $this->name = request()->get('name');
        //dd($this->name);
        if ($rs = $this->model->where('name', $this->name)->first()) {
            return redirect()->route('admin.set.edit', ['set' => $rs->id]);
        }
        return $content
            ->title($this->title())
            ->description($this->desc['create'] ?? trans('admin.create'))
            ->body($this->form());
    }

    /**
     * Update the specified resource in storage.
     *
     * @param int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function update($set)
    {
        $rs = $this->model->where('name', $set)->orWhere('id', $set)->firstOrFail();
        $id = $rs->id;
        $this->name = $rs->name;
        return $this->form()->update($id);
    }

    /**
     * Store a newly created resource in storage.
     *
     * @return mixed
     */
    public function store()
    {
        $this->name = request()->get('name');
        return $this->form()->store();
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($set)
    {
        $rs = $this->model->where('name', $set)->orWhere('id', $set)->first();
        $id = $rs->id;
        return $this->form()->destroy($id);
    }

    /**
     * Make a grid builder.
     *
     * @return Grid
     */
    protected function grid()
    {
        $grid = new Grid($this->model);
        $grid->column('id', 'ID')->sortable();
        $grid->column('name', trans('name'));
        $grid->column('sets', trans('sets'));
        $grid->column('created_at', trans('admin.created_at'));
        $grid->column('updated_at', trans('admin.updated_at'));

        $grid->actions(function (Grid\Displayers\Actions $actions) {
            if ($actions->getKey() == 1) {
                $actions->disableDelete();
            }
        });

        $grid->tools(function (Grid\Tools $tools) {
            $tools->batch(function (Grid\Tools\BatchActions $actions) {
                $actions->disableDelete();
            });
        });

        return $grid;
    }

    /**
     * Make a show builder.
     *
     * @param mixed $id
     *
     * @return Show
     */
    protected function detail($set)
    {
        $show = new Show($this->model->where('name', $set)->orWhere('id', $set)->firstOrFail());
        $show->field('id', 'ID');
        $show->field('name', '标识');
        $show->field('sets', '设置');
        $show->field('created_at', trans('admin.created_at'));
        $show->field('updated_at', trans('admin.updated_at'));
        return $show;
    }

    /**
     * Make a form builder.
     *
     * @return Form
     */
    public function form()
    {
        $form = new Form($this->model);
        $name = $this->name;

        $tm = explode('.', $name);
        $table = $tm[0];
        if (!empty($tm[1])) {
            $model = '\\' . $tm[1];
        } else {
            $model = false;
        }

        if ($model && method_exists($model, 'getSetsForm')) {
            $sourceModel = new $model();
            $fields = $sourceModel->getSetsForm();
            $update_replace = $sourceModel->getUpdateReplace() ?? [];
        } else {
            $fields = config('tables.' . $table . '.sets_form');
            $update_replace = config('tables.' . $table . '.sets_form_update_replace') ?? [];
        }

        if ($form->isCreating()) {
            $form->hidden('name', '标识')->value($this->name);
        } else {
            $form->hidden('name', '标识')->value($this->name);
            $fields = array_merge($fields, $update_replace);
        }

        $form->embeds('sets', function ($form) use ($fields) {
            foreach ($fields as $field => $value) {
                if (empty($value) || !is_array($value)) continue;  //忽略
                $i = 0;
                $has = 0;
                foreach ($value as $k => $v) {
                    if ($i === 0) {
                        if (is_numeric($field)) { //附加功能,如saving等
                            $form->$k($v);
                            continue;
                        }
                        $v = str2arr($v);
                        if ($className = Form::findFieldClass($k)) {  //存在field类,如 text('desc','说明')
                            $element = new $className($field, $v);
                            $has = 1;
                        } else {
                            continue;
                        }
                    } else {
                        if (is_null($v) || in_array($k, ['required', 'readonly', 'disable', 'autofocus', 'stacked', 'canCheckAll', 'removable', 'retainable', 'downloadable', 'sortable'])) {    //无参数样式,如required();
                            $element = $element->$k();
                        } else {
                            $element = $element->$k($v);
                        }
                    }
                    $i++;
                }
                if ($has)  $form->pushField($element);
            }
        });
        return $form;
    }
}
